package com.bzframework.pro.api.core.mock;

import com.bzframework.pro.api.core.provider.ApiSupport;
import com.bzframework.pro.api.core.provider.ApiSupportManager;
import com.bzframework.pro.api.core.provider.ApiSupportProvider;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author bingzhong
 * @Date 2025/2/28 11:35
 * @Description
 */
@Component
@RequiredArgsConstructor
public class MockRunner implements CommandLineRunner {

    private final ApiSupportManager apiSupportManager;

    private static List<MetadataReader> classResources;

    @Override
    public void run(String... args) throws Exception {
        parseJar();
    }

    private void parseJar() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        //        String location = "file:D:\\open-api-platform-1.0.0-SNAPSHOT.jar";
        String location = "file:D:\\scaffolding\\bandage\\bandage-backend\\bzframework-components\\openapi-component\\target\\openapi-component-1.0.0-SNAPSHOT.jar";


//        Class<?> loadClass = classLoader.loadClass(ApiSupportProvider.class.getName());
//        ApiSupportProvider apiSupportProvider = (ApiSupportProvider) loadClass.getConstructor().newInstance();
//        ApiSupport apiSupport = apiSupportProvider.create().blockFirst();
//        String name = apiSupport.getName();
//        System.out.println("name = " + name);
        PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver() {
            @Override
            protected boolean isJarResource(@NonNull Resource resource) {
                return true;
            }
        };
        location = "jar:"+ location +"!/**/*.class";
        CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
        Resource[] classes = resourcePatternResolver.getResources(location);
        classResources = new ArrayList<>(classes.length);
        for (Resource aClass : classes) {
            classResources.add(metadataReaderFactory.getMetadataReader(aClass));
        }
        URL url = new File(location).toURI().toURL();
        URLClassLoader classLoader = new URLClassLoader(
                new URL[]{url},
                Thread.currentThread().getContextClassLoader() // 使用当前线程的类加载器作为父类加载器
        );
        List<ApiSupport> apiSupports = new ArrayList<>();
        for (MetadataReader metadataReader : classResources) {
            String className = metadataReader.getClassMetadata().getClassName();
            Class<?> aClass = classLoader.loadClass(className);
            if (!ApiSupportProvider.class.isAssignableFrom(aClass) || aClass.isInterface()) {
                continue;
            }
            ApiSupportProvider apiSupportProvider = (ApiSupportProvider) aClass.getDeclaredConstructor().newInstance();
            apiSupports.addAll(apiSupportProvider.create());
        }
        apiSupports.forEach(apiSupportManager::register);
        System.out.println("apiSupportManager.getApiSupports().size() = " + apiSupportManager.getApiSupports().size());
        metadataReaderFactory.clearCache();
    }
}
